package com.common.utils;

import com.common.constants.DateFormatConstantPool;
import com.common.constants.RegularExpressionConstantPool;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @Brief 时间函数相关工具类
 * @Author chenyl
 * @Date 2023-08-07
 * @Version 1.0.0
 */
public class DateUtil {

    public static <T> T toDate(String dateStr, Class<T> clazz) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        // Date类型就直接返回
        Date date = convertDate(dateStr);
        if (clazz.equals(Date.class)) {
            return (T) date;
        }
        // LocalDateTime系列需要再做处理
        Instant instant = date.toInstant();
        if (clazz.equals(LocalDateTime.class)) {
            return (T) instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
        }
        if (clazz.equals(LocalDate.class)) {
            return (T) instant.atZone(ZoneId.systemDefault()).toLocalDate();
        }
        if (clazz.equals(LocalTime.class)) {
            return (T) instant.atZone(ZoneId.systemDefault()).toLocalTime();
        }
        return null;
    }

    /**
     * 将时间通过指定格式转换成时间字符串
     *
     * @param date   时间
     * @param format 时间格式字符串
     * @return 时间字符串
     */
    public static String toDateStr(Object date, String format) {
        // 判断参数均是否有值
        if (StringUtils.isEmpty(date) || StringUtils.isEmpty(format)) {
            return null;
        }
        // 转换时间格式函数
        DateTimeFormatter formatter;
        try {
            formatter = DateTimeFormatter.ofPattern(format);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        // 判断是否为LocalDateTime的实例对象
        if (date instanceof LocalDateTime) {
            return localDateTimeToDateStr((LocalDateTime) date, formatter);
        }
        // 判断是否为LocalDate的实例函数
        if (date instanceof LocalDate) {
            return localDateToDateStr((LocalDate) date, formatter);
        }
        // 判断是否为Date的实例函数
        if (date instanceof Date) {
            return dateToDateStr((Date) date, format);
        }
        return null;
    }

    /**
     * 将LocalDateTime转换成字符串
     *
     * @param dateTime  LocalDateTime
     * @param formatter 时间格式
     * @return 时间字符串
     */
    private static String localDateTimeToDateStr(LocalDateTime dateTime, DateTimeFormatter formatter) {
        try {
            return dateTime.format(formatter);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将LocalDate转换成字符串
     *
     * @param date      LocalDate
     * @param formatter 时间格式
     * @return 时间字符串
     */
    private static String localDateToDateStr(LocalDate date, DateTimeFormatter formatter) {
        try {
            return date.format(formatter);
        } catch (Exception e) {
            try {
                return date.atStartOfDay().format(formatter);
            } catch (Exception e1) {
                e.printStackTrace();
                return null;
            }
        }
    }

    /**
     * 将Date转换成字符串
     *
     * @param date   date
     * @param format 时间格式字符串
     * @return 时间字符串
     */
    private static String dateToDateStr(Date date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将时间字符串转换成时间
     *
     * @param dateStr 时间字符串
     * @return date对象
     */
    private static Date convertDate(String dateStr) {
        boolean matcher = StringUtils.matcher(RegularExpressionConstantPool.DATE_TIME_FORMAT, dateStr);
        if (matcher) {
            for (String format : DateFormatConstantPool.DATE_TIME_FORMAT_LIST) {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                try {
                    return sdf.parse(dateStr);
                } catch (Exception e) {
                    System.out.println("时间格式：" + format + "不匹配");
                }
            }
            throw new DateTimeException("未匹配到对应的时间格式");
        }
        matcher = StringUtils.matcher(RegularExpressionConstantPool.DATE_FORMAT, dateStr);
        if (matcher) {
            for (String format : DateFormatConstantPool.DATE_FORMAT_LIST) {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                try {
                    return sdf.parse(dateStr);
                } catch (Exception e) {
                    System.out.println("时间格式：" + format + "不匹配");
                }
            }
            throw new DateTimeException("未匹配到对应的时间格式");
        }
        matcher = StringUtils.matcher(RegularExpressionConstantPool.TIME_FORMAT, dateStr);
        if (matcher) {
            for (String format : DateFormatConstantPool.TIME_FORMAT_LIST) {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                try {
                    return sdf.parse(dateStr);
                } catch (Exception e) {
                    System.out.println("时间格式：" + format + "不匹配");
                }
            }
            throw new DateTimeException("未匹配到对应的时间格式");
        }
        throw new RuntimeException("时间字符串不正确");
    }
}
